package com.web.interceptor;

import org.hibernate.*;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.*;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class OpenSessionInViewInterceptor extends AbstractInterceptor {

	private static final long serialVersionUID = 1L;

	private SessionFactory sessionFactory;

	@SuppressWarnings("deprecation")
	private FlushMode flushMode = FlushMode.NEVER;

	@Override
	public String intercept(ActionInvocation action) throws Exception {
		boolean participate = false;

		if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
			participate = true;
		} else {
			Session session = getSession(sessionFactory);
			TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
		}

		try {
			return action.invoke();
		} finally {
			if (!participate) {
				SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
				closeSession(sessionHolder.getSession());
			}
		}
	}

	private Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
		Session session = SessionFactoryUtils.getSession(sessionFactory, true);
		if (flushMode != null) {
			session.setFlushMode(flushMode);
		}
		return session;
	}

	private void closeSession(Session session) {
		SessionFactoryUtils.closeSession(session);
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}